// 智能提醒服务 - 基于AI算法优化提醒时间
import { EnhancedNotificationService } from './enhancedNotification';

export interface UserBehaviorData {
  userId: string;
  workingHours: {
    start: number; // 0-23
    end: number;   // 0-23
    timezone: string;
  };
  productivityPeaks: number[]; // 高效时间段 (0-23)
  taskCompletionPatterns: {
    timeOfDay: number;
    completionRate: number;
    taskType: string;
  }[];
  preferredBreakTimes: number[]; // 休息时间
  deviceUsagePatterns: {
    hour: number;
    activeTime: number; // 分钟
    notificationResponseRate: number;
  }[];
  locationPatterns?: {
    location: string;
    timeSpent: number;
    taskTypes: string[];
  }[];
}

export interface TaskContext {
  id: string;
  title: string;
  description?: string;
  priority: 'low' | 'normal' | 'high' | 'urgent';
  complexity: 'simple' | 'medium' | 'complex';
  estimatedDuration: number; // 分钟
  dueDate: Date;
  category: string;
  tags: string[];
  dependencies: string[]; // 依赖的任务ID
  location?: string;
  requiredFocus: 'low' | 'medium' | 'high'; // 需要的专注度
}

export interface SmartReminderOptions {
  minLeadTime: number; // 最小提前时间（分钟）
  maxLeadTime: number; // 最大提前时间（分钟）
  preferredReminderCount: number; // 期望的提醒次数
  respectWorkingHours: boolean;
  considerProductivityPeaks: boolean;
  adaptToUserBehavior: boolean;
  includeBufferTime: boolean; // 是否包含缓冲时间
}

export interface SmartReminder {
  id: string;
  taskId: string;
  scheduledTime: Date;
  type: 'preparation' | 'focus' | 'final' | 'urgent';
  message: string;
  priority: 'low' | 'normal' | 'high' | 'urgent';
  confidence: number; // 0-1, 算法对这个时间的信心度
  reasoning: string; // 选择这个时间的原因
  adaptable: boolean; // 是否可以根据实时情况调整
}

export class SmartReminderService {
  private static instance: SmartReminderService;
  private notificationService: EnhancedNotificationService;
  private userBehaviorData: Map<string, UserBehaviorData> = new Map();
  private activeReminders: Map<string, SmartReminder[]> = new Map();
  private learningData: Map<string, any> = new Map();

  private constructor() {
    this.notificationService = EnhancedNotificationService.getInstance();
    this.loadUserBehaviorData();
    this.startAdaptiveLearning();
  }

  public static getInstance(): SmartReminderService {
    if (!SmartReminderService.instance) {
      SmartReminderService.instance = new SmartReminderService();
    }
    return SmartReminderService.instance;
  }

  // 为任务创建智能提醒
  public async createSmartReminders(
    task: TaskContext,
    userId: string,
    options: Partial<SmartReminderOptions> = {}
  ): Promise<SmartReminder[]> {
    const defaultOptions: SmartReminderOptions = {
      minLeadTime: 15,
      maxLeadTime: 4320, // 3天
      preferredReminderCount: 3,
      respectWorkingHours: true,
      considerProductivityPeaks: true,
      adaptToUserBehavior: true,
      includeBufferTime: true,
      ...options
    };

    const userBehavior = this.userBehaviorData.get(userId);
    const now = new Date();
    const timeUntilDue = task.dueDate.getTime() - now.getTime();

    if (timeUntilDue <= 0) {
      console.warn('任务已过期，无法创建提醒');
      return [];
    }

    // 计算基础提醒时间点
    const baseReminderTimes = this.calculateBaseReminderTimes(task, defaultOptions);
    
    // 应用用户行为优化
    const optimizedTimes = userBehavior && defaultOptions.adaptToUserBehavior
      ? this.optimizeWithUserBehavior(baseReminderTimes, task, userBehavior, defaultOptions)
      : baseReminderTimes;

    // 应用生产力峰值优化
    const productivityOptimizedTimes = userBehavior && defaultOptions.considerProductivityPeaks
      ? this.optimizeWithProductivityPeaks(optimizedTimes, task, userBehavior)
      : optimizedTimes;

    // 创建智能提醒对象
    const smartReminders = this.createReminderObjects(
      productivityOptimizedTimes,
      task,
      userId,
      defaultOptions
    );

    // 过滤掉已过期的提醒
    const validReminders = smartReminders.filter(reminder => 
      reminder.scheduledTime > now
    );

    // 存储活跃提醒
    this.activeReminders.set(task.id, validReminders);

    // 安排实际的通知
    await this.scheduleNotifications(validReminders, task);

    return validReminders;
  }

  // 更新用户行为数据
  public updateUserBehavior(userId: string, behaviorData: Partial<UserBehaviorData>): void {
    const existing = this.userBehaviorData.get(userId) || this.getDefaultUserBehavior(userId);
    const updated = { ...existing, ...behaviorData };
    this.userBehaviorData.set(userId, updated);
    this.saveUserBehaviorData();
  }

  // 记录用户对提醒的反应（用于学习）
  public recordReminderInteraction(
    reminderId: string,
    interaction: 'clicked' | 'dismissed' | 'snoozed' | 'acted',
    context: {
      timeOfDay: number;
      taskCompleted: boolean;
      delayMinutes?: number;
    }
  ): void {
    const learningKey = `reminder_${reminderId}`;
    const learningRecord = {
      reminderId,
      interaction,
      context,
      timestamp: Date.now()
    };

    const existing = this.learningData.get(learningKey) || [];
    existing.push(learningRecord);
    this.learningData.set(learningKey, existing);

    // 触发自适应学习
    this.updateLearningModel(reminderId, learningRecord);
  }

  // 获取用户的提醒效果分析
  public getReminderAnalytics(userId: string): {
    effectiveness: number;
    bestTimes: number[];
    worstTimes: number[];
    recommendedImprovements: string[];
  } {

    const interactions = Array.from(this.learningData.values()).flat()
      .filter(record => record.reminderId.includes(userId));

    // 计算效果指标
    const effectiveness = this.calculateEffectiveness(interactions);
    const timeAnalysis = this.analyzeTimeEffectiveness(interactions);
    const improvements = this.generateImprovementRecommendations(effectiveness, timeAnalysis);

    return {
      effectiveness,
      bestTimes: timeAnalysis.bestTimes,
      worstTimes: timeAnalysis.worstTimes,
      recommendedImprovements: improvements
    };
  }

  // 私有方法

  private calculateBaseReminderTimes(
    task: TaskContext,
    options: SmartReminderOptions
  ): Date[] {
    const now = new Date();
    const dueDate = task.dueDate;
    const timeUntilDue = dueDate.getTime() - now.getTime();
    const hoursUntilDue = timeUntilDue / (1000 * 60 * 60);

    // 根据任务复杂度和优先级确定提醒策略
    const complexityMultipliers = {
      simple: [0.1, 0.3], // 10%, 30% of time until due
      medium: [0.1, 0.3, 0.6], // 10%, 30%, 60%
      complex: [0.1, 0.25, 0.5, 0.75] // 10%, 25%, 50%, 75%
    };

    const priorityAdjustments = {
      low: 0.8,
      normal: 1.0,
      high: 1.2,
      urgent: 1.5
    };

    let multipliers = complexityMultipliers[task.complexity];
    const priorityFactor = priorityAdjustments[task.priority];

    // 调整提醒次数
    if (options.preferredReminderCount < multipliers.length) {
      multipliers = multipliers.slice(0, options.preferredReminderCount);
    }

    // 计算提醒时间
    const reminderTimes: Date[] = [];
    
    multipliers.forEach(multiplier => {
      const adjustedMultiplier = multiplier * priorityFactor;
      const leadTimeHours = Math.max(
        hoursUntilDue * adjustedMultiplier,
        options.minLeadTime / 60
      );
      
      const leadTimeMs = Math.min(
        leadTimeHours * 60 * 60 * 1000,
        options.maxLeadTime * 60 * 1000
      );

      const reminderTime = new Date(dueDate.getTime() - leadTimeMs);
      
      if (reminderTime > now) {
        reminderTimes.push(reminderTime);
      }
    });

    return reminderTimes.sort((a, b) => a.getTime() - b.getTime());
  }

  private optimizeWithUserBehavior(
    baseTimes: Date[],
    _task: TaskContext,
    userBehavior: UserBehaviorData,
    options: SmartReminderOptions
  ): Date[] {
    return baseTimes.map(time => {
      const hour = time.getHours();
      
      // 检查是否在工作时间内
      if (options.respectWorkingHours) {
        const { start, end } = userBehavior.workingHours;
        
        if (hour < start) {
          // 推迟到工作开始时间
          const adjusted = new Date(time);
          adjusted.setHours(start, 0, 0, 0);
          return adjusted;
        } else if (hour >= end) {
          // 提前到工作结束前1小时
          const adjusted = new Date(time);
          adjusted.setHours(Math.max(end - 1, start), 0, 0, 0);
          return adjusted;
        }
      }

      // 检查设备使用模式
      const deviceUsage = userBehavior.deviceUsagePatterns.find(
        pattern => pattern.hour === hour
      );

      if (deviceUsage && deviceUsage.notificationResponseRate < 0.3) {
        // 如果这个时间段响应率低，寻找附近更好的时间
        const betterHour = this.findBetterNearbyHour(hour, userBehavior);
        if (betterHour !== hour) {
          const adjusted = new Date(time);
          adjusted.setHours(betterHour);
          return adjusted;
        }
      }

      return time;
    });
  }

  private optimizeWithProductivityPeaks(
    times: Date[],
    task: TaskContext,
    userBehavior: UserBehaviorData
  ): Date[] {
    // 如果任务需要高专注度，尽量安排在生产力峰值前提醒
    if (task.requiredFocus === 'high' && userBehavior.productivityPeaks.length > 0) {
      return times.map(time => {
        const hour = time.getHours();
        const nearestPeak = this.findNearestProductivityPeak(hour, userBehavior.productivityPeaks);
        
        if (nearestPeak !== null && Math.abs(nearestPeak - hour) <= 2) {
          // 在生产力峰值前30分钟提醒
          const adjusted = new Date(time);
          adjusted.setHours(nearestPeak, 0, 0, 0);
          adjusted.setTime(adjusted.getTime() - (30 * 60 * 1000));
          return adjusted;
        }
        
        return time;
      });
    }

    return times;
  }

  private createReminderObjects(
    times: Date[],
    task: TaskContext,
    userId: string,
    _options: SmartReminderOptions
  ): SmartReminder[] {
    const reminders: SmartReminder[] = [];
    const now = new Date();

    times.forEach((time, index) => {
      const timeUntilReminder = time.getTime() - now.getTime();
      const hoursUntilReminder = timeUntilReminder / (1000 * 60 * 60);
      
      let type: SmartReminder['type'];
      let message: string;
      let priority: SmartReminder['priority'];

      // 根据时间距离确定提醒类型
      if (hoursUntilReminder > 24) {
        type = 'preparation';
        message = `准备开始任务"${task.title}"`;
        priority = 'low';
      } else if (hoursUntilReminder > 2) {
        type = 'focus';
        message = `任务"${task.title}"需要您的关注`;
        priority = 'normal';
      } else if (hoursUntilReminder > 0.5) {
        type = 'final';
        message = `任务"${task.title}"即将到期`;
        priority = 'high';
      } else {
        type = 'urgent';
        message = `紧急：任务"${task.title}"马上到期！`;
        priority = 'urgent';
      }

      const reminder: SmartReminder = {
        id: `smart_${task.id}_${index}_${Date.now()}`,
        taskId: task.id,
        scheduledTime: time,
        type,
        message,
        priority,
        confidence: this.calculateConfidence(time, task, userId),
        reasoning: this.generateReasoning(time, task, type),
        adaptable: type !== 'urgent'
      };

      reminders.push(reminder);
    });

    return reminders;
  }

  private async scheduleNotifications(
    reminders: SmartReminder[],
    task: TaskContext
  ): Promise<void> {
    for (const reminder of reminders) {
      const delay = reminder.scheduledTime.getTime() - Date.now();
      
      if (delay > 0) {
        setTimeout(async () => {
          await this.notificationService.showEnhancedNotification({
            title: this.getReminderTitle(reminder.type),
            body: reminder.message,
            priority: reminder.priority,
            category: 'reminder',
            data: {
              taskId: task.id,
              reminderId: reminder.id,
              type: reminder.type
            },
            actions: this.getReminderActions(reminder.type),
            onClick: () => {
              this.recordReminderInteraction(reminder.id, 'clicked', {
                timeOfDay: new Date().getHours(),
                taskCompleted: false
              });
            }
          });
        }, delay);
      }
    }
  }

  private findBetterNearbyHour(
    currentHour: number,
    userBehavior: UserBehaviorData
  ): number {
    const searchRange = 2; // 搜索前后2小时
    let bestHour = currentHour;
    let bestResponseRate = 0;

    for (let offset = -searchRange; offset <= searchRange; offset++) {
      const hour = (currentHour + offset + 24) % 24;
      const pattern = userBehavior.deviceUsagePatterns.find(p => p.hour === hour);
      
      if (pattern && pattern.notificationResponseRate > bestResponseRate) {
        bestResponseRate = pattern.notificationResponseRate;
        bestHour = hour;
      }
    }

    return bestHour;
  }

  private findNearestProductivityPeak(
    hour: number,
    productivityPeaks: number[]
  ): number | null {
    if (productivityPeaks.length === 0) return null;

    let nearest = productivityPeaks[0];
    let minDistance = Math.abs(hour - nearest);

    for (const peak of productivityPeaks) {
      const distance = Math.abs(hour - peak);
      if (distance < minDistance) {
        minDistance = distance;
        nearest = peak;
      }
    }

    return minDistance <= 3 ? nearest : null; // 只考虑3小时内的峰值
  }

  private calculateConfidence(
    time: Date,
    _task: TaskContext,
    userId: string
  ): number {
    let confidence = 0.5; // 基础信心度

    const userBehavior = this.userBehaviorData.get(userId);
    if (userBehavior) {
      const hour = time.getHours();
      
      // 基于设备使用模式调整
      const devicePattern = userBehavior.deviceUsagePatterns.find(p => p.hour === hour);
      if (devicePattern) {
        confidence += devicePattern.notificationResponseRate * 0.3;
      }

      // 基于生产力峰值调整
      if (userBehavior.productivityPeaks.includes(hour)) {
        confidence += 0.2;
      }

      // 基于工作时间调整
      const { start, end } = userBehavior.workingHours;
      if (hour >= start && hour < end) {
        confidence += 0.2;
      }
    }

    return Math.min(Math.max(confidence, 0), 1);
  }

  private generateReasoning(time: Date, task: TaskContext, type: string): string {
    const hour = time.getHours();
    const reasons: string[] = [];

    if (type === 'preparation') {
      reasons.push('提前准备时间充足');
    } else if (type === 'urgent') {
      reasons.push('临近截止时间');
    }

    if (hour >= 9 && hour <= 17) {
      reasons.push('工作时间内');
    }

    if (task.priority === 'urgent') {
      reasons.push('高优先级任务');
    }

    return reasons.join(', ') || '基于默认算法';
  }

  private getReminderTitle(type: string): string {
    const titles = {
      preparation: '📋 任务准备提醒',
      focus: '🎯 任务关注提醒',
      final: '⏰ 任务临期提醒',
      urgent: '🚨 紧急任务提醒'
    };
    return titles[type as keyof typeof titles] || '📋 任务提醒';
  }

  private getReminderActions(type: string): Array<{action: string, title: string}> {
    const baseActions = [
      { action: 'view', title: '查看任务' },
      { action: 'snooze', title: '稍后提醒' }
    ];

    if (type === 'urgent') {
      return [
        { action: 'view', title: '立即处理' },
        { action: 'extend', title: '申请延期' }
      ];
    }

    if (type === 'preparation') {
      return [
        ...baseActions,
        { action: 'start', title: '开始准备' }
      ];
    }

    return baseActions;
  }

  private getDefaultUserBehavior(userId: string): UserBehaviorData {
    return {
      userId,
      workingHours: {
        start: 9,
        end: 18,
        timezone: 'Asia/Shanghai'
      },
      productivityPeaks: [9, 14, 16],
      taskCompletionPatterns: [],
      preferredBreakTimes: [12, 15],
      deviceUsagePatterns: Array.from({ length: 24 }, (_, hour) => ({
        hour,
        activeTime: hour >= 8 && hour <= 22 ? 30 : 5,
        notificationResponseRate: hour >= 9 && hour <= 17 ? 0.7 : 0.3
      }))
    };
  }

  private startAdaptiveLearning(): void {
    // 每小时分析一次学习数据并调整算法
    setInterval(() => {
      this.analyzeLearningData();
    }, 60 * 60 * 1000);
  }

  private analyzeLearningData(): void {
    // 分析用户交互数据，调整未来的提醒策略
    // 这里可以实现更复杂的机器学习算法
    console.log('分析学习数据并更新提醒策略');
  }

  private updateLearningModel(reminderId: string, record: any): void {
    // 实时更新学习模型
    // 可以基于用户的即时反馈调整后续提醒
    console.log('更新学习模型:', reminderId, record);
  }

  private calculateEffectiveness(interactions: any[]): number {
    if (interactions.length === 0) return 0.5;

    const positiveInteractions = interactions.filter(
      i => i.interaction === 'clicked' || i.interaction === 'acted'
    ).length;

    return positiveInteractions / interactions.length;
  }

  private analyzeTimeEffectiveness(interactions: any[]): {
    bestTimes: number[];
    worstTimes: number[];
  } {
    const hourStats = new Map<number, { positive: number; total: number }>();

    interactions.forEach(interaction => {
      const hour = interaction.context.timeOfDay;
      const stats = hourStats.get(hour) || { positive: 0, total: 0 };
      
      stats.total++;
      if (interaction.interaction === 'clicked' || interaction.interaction === 'acted') {
        stats.positive++;
      }
      
      hourStats.set(hour, stats);
    });

    const hourEffectiveness = Array.from(hourStats.entries())
      .map(([hour, stats]) => ({
        hour,
        effectiveness: stats.positive / stats.total
      }))
      .sort((a, b) => b.effectiveness - a.effectiveness);

    const bestTimes = hourEffectiveness.slice(0, 3).map(h => h.hour);
    const worstTimes = hourEffectiveness.slice(-3).map(h => h.hour);

    return { bestTimes, worstTimes };
  }

  private generateImprovementRecommendations(
    effectiveness: number,
    timeAnalysis: { bestTimes: number[]; worstTimes: number[] }
  ): string[] {
    const recommendations: string[] = [];

    if (effectiveness < 0.3) {
      recommendations.push('考虑减少提醒频率，避免打扰过度');
    }

    if (timeAnalysis.bestTimes.length > 0) {
      recommendations.push(
        `建议在 ${timeAnalysis.bestTimes.join(', ')} 点发送重要提醒`
      );
    }

    if (timeAnalysis.worstTimes.length > 0) {
      recommendations.push(
        `避免在 ${timeAnalysis.worstTimes.join(', ')} 点发送提醒`
      );
    }

    return recommendations;
  }

  private loadUserBehaviorData(): void {
    try {
      const saved = localStorage.getItem('smart-reminder-user-behavior');
      if (saved) {
        const data = JSON.parse(saved);
        this.userBehaviorData = new Map(Object.entries(data));
      }
    } catch (error) {
      console.error('加载用户行为数据失败:', error);
    }
  }

  private saveUserBehaviorData(): void {
    try {
      const data = Object.fromEntries(this.userBehaviorData);
      localStorage.setItem('smart-reminder-user-behavior', JSON.stringify(data));
    } catch (error) {
      console.error('保存用户行为数据失败:', error);
    }
  }
}

export default SmartReminderService;
